module ActionController
	class Base 
		SPRING_WRAPPER_TYPE = :jquery
		
		# --------------------------------------------------------------------------
		# Queue some JS to be inserted at the bottom of the page, as is the proper thing to 
		# do for optimal page load times
		# -params-
		# queue_type: if :execute, it gets wrapped in JS that will automatically execute after the document loads (e.g., jQuery(function(){ ... });)
		#							if :flat, it gets wrapped in just a plain old javascript_tag
		helper_method :queue_js
		def queue_js(queue_type = :execute)
			flash.now[:js_jquery_queue] ||= ""
			flash.now[:js_flat_queue] ||= ""
			
			if queue_type == :execute
				flash.now[:js_jquery_queue] += yield + "\n"
			elsif queue_type == :flat
				flash.now[:js_flat_queue] += yield + "\n"
			end		
		end
		
		# --------------------------------------------------------------------------
		# Return all the queued JS onto the page, and clear the queues
		helper_method :unqueue_js
		def unqueue_js
			js_jquery, js_flat = flash.now[:js_jquery_queue], flash.now[:js_flat_queue]		
			inner_data = ""
			
			if js_flat && !js_flat.empty?
				inner_data += %{#{js_flat}\n}
			end
			
			if js_jquery && !js_jquery.empty?
				case SPRING_WRAPPER_TYPE
					when :jquery:
						inner_data += %{jQuery(function(){\n#{js_jquery}\n});}
					when :prototype:
						inner_data += %{jspringInit = function(){\n#{js_jquery}\n}\nEvent.observe(window,'load',jspringInit,false);} 
				end
			end
			
			# javascript_tag not accessible from ActionController, so commence hacking, er, simulating what the tag_helper does when you run javascript_tag.
			return_str = %{<script>\n\n//<![CDATA[\n#{inner_data}\n//]]>\n</script>} if inner_data && !inner_data.empty?
			flash.now[:js_jquery_queue], flash.now[:js_flat_queue] = "", ""
			return_str
		end
		
		# --------------------------------------------------------------------------
		# If we rendered a partial (through a controller call only, since this method is only accessible to
		# controllers (as it should be.  We wouldn't want views having this alias chain or it would defeat the point
		# since JS would be spit out all over the page)), ensure that any queued JS in that partial gets appended, thus run
		def render_with_jsunqueue(options = nil, deprecated_status = nil, &block)					
			render_without_jsunqueue(options, &block)
			# If we're rendering a partial from a controller, ensure that any queued JS in that partial gets executed.  Without manually
			# calling it.  Also assume we want to unqueue JS if we're rendering an action
			# options == nil when render called implicitly (by format.html and the like)
			if((options == nil) || (options && options.is_a?(Hash) && (options[:partial] || options[:action])))
				js_text = unqueue_js
				if js_text && !js_text.empty?
					response.body << js_text
				end
			end		
		end
		alias_method_chain :render, :jsunqueue
		
	end
end
